using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using Microsoft.WowAddonStudio.FrameXml.Components;
using Microsoft.WowAddonStudio.FrameXml.Design.Serialization;
using Microsoft.WowAddonStudio.FrameXml.Serialization.LayoutFrames;
using Microsoft.WowAddonStudio.Tests.Common.Mocks;

using NUnit.Framework;

namespace Microsoft.WowAddonStudio.FrameXml.Design.Tests.Serialization
{
	[TestFixture]
	public sealed class FrameXmlSerializationStoreTest : SerializationTestBase
	{

		#region SetUp

		[TestFixtureSetUp]
		public void TestFixtureSetUp()
		{
			serializer = new FrameXmlRuntimeSerializer();
			locator = new SimpleTestServiceLocator();
		}

		[SetUp]
		public void SetUp()
		{
			serializationStore = new FrameXmlSerializationStore(locator);
		}

		#endregion

		#region TearDown

		[TearDown]
		public void TearDown()
		{
		}

		#endregion

		#region Tests

		[Test(Description = "")]
		[ExpectedException(typeof(ArgumentNullException))]
		public void Test_InitFailed()
		{
			new FrameXmlSerializationStore(null);
		}

		[Test(Description = "")]
		public void Test_DeSerialize()
		{
			serializationStore = CreateFakeSerializationStore();

			Assert.IsNotNull(serializationStore);
			Assert.IsNotNull(serializationStore.Errors);
			Assert.AreEqual(1, serializationStore.Count);

			var deserializedResult = serializationStore.Deserialize(locator, locator, serializer);

			Assert.IsNotNull(deserializedResult);
			Assert.AreEqual(1, deserializedResult.Count);
			var frame = deserializedResult.OfType<Frame>().SingleOrDefault();
			Assert.IsNotNull(frame);
			Assert.AreEqual("TestControl", frame.Name);

			Assert.IsNotNull(serializationStore.Errors);
			Assert.AreEqual(0, serializationStore.Errors.Count);
		}

		[Test(Description = "")]
		[ExpectedException(typeof(ArgumentNullException))]
		public void Test_DeSerializeFailed()
		{
			serializationStore.Deserialize(null, null);
		}
				
		/// <summary>
		/// Creates the fake serialization store.
		/// </summary>
		private FrameXmlSerializationStore CreateFakeSerializationStore()
		{
			var frame = (Frame) ((IFrameXmlControl)CreateTestControl()).SerializationObject;
			
			var info = new SerializationInfo(typeof(FrameXmlSerializationStore), new FormatterConverter());
			var context = new StreamingContext();

			info.AddValue("Elements", new Dictionary<string, string>() { { frame.Name, serializer.Serialize(frame) } });
			info.AddValue("RuntimeTypes", new Dictionary<string, Type>() { { frame.Name, frame.GetType() } });
			info.AddValue("Names", new List<string>() { frame.Name});

			return new FrameXmlSerializationStore(info, context);
		}

		#endregion
	}
}